﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Niti.OrderManage.DTO;
using Niti.OrderManage.Eto;
using Niti.OrderManage.OrderManage;
using Niti.OrderManage.OrderManage.Enum;
using Niti.OrderManage.OrderManage.Repositories;
using Niti.OrderManage.OrderManage.ValueObject;
using Niti.OrderManage.ToolKits.Base;
using Niti.OrderManage.ToolKits.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Uow;
using static Niti.OrderManage.NitiOrderManageConsts;

namespace Niti.OrderManage.Order.Impl
{

    [ApiController]
    [Route("[controller]/[action]")]
    [ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
    public class CheckOutOrderManageService: NitiOrderManageApplicationServiceBase
    {
        private readonly ICheckOutOrderRepository _checkoutorderRepository;
        private readonly ICheckOutOrderLineItemRepository _checkoutorderLineItemRepository;

        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly ILogger _logger;
        private readonly ILocalEventBus _localEventBus;

        public CheckOutOrderManageService(
            ICheckOutOrderRepository checkoutorderRepository,
           ICheckOutOrderLineItemRepository checkoutorderLineItemRepository,
            IUnitOfWorkManager unitOfWorkManager,
            ILogger<CheckOutOrderManageService> logger,
            ILocalEventBus localEventBus)
        {

            _checkoutorderRepository = checkoutorderRepository;
            _checkoutorderLineItemRepository = checkoutorderLineItemRepository;
            _unitOfWorkManager = unitOfWorkManager;
            _logger = logger;
            _localEventBus = localEventBus;
        }

        #region 订单操作
        /// <summary>
        /// 新增订单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ServiceResult<string>> InsertOrderAsync(AddCheckOutOrderDto dto)
        {
            var result = new ServiceResult<string>();
            try
            {
                //查询是否有该订单
                var entityExist = await _checkoutorderRepository.FindAsync(x => x.Code == dto.Code);
                if (entityExist != null)
                {
                    result.IsFailed(ResponseText.INSERT_FAILED + ",已存在该订单");
                    return result;
                }

                //订单
                var orderentity = new CheckOutOrder(dto.Code,dto.ApplyUser,dto.Description);
                //订单明细   
                foreach (var item in dto.CheckOutItem)
                {
                    //订单明细商品
                    var orderLineItem_Commodity = new OrderLineItem_Commodity(item.Commodity_Code, item.Commodity_CName, item.Commodity_CPrice);

                    //发布商品校验事件
                    var count=  await PublishCommodityAsync(orderLineItem_Commodity);

                    if (item.Count > count)
                    {
                        result.IsFailed(ResponseText.INSERT_FAILED + ",商品编号："+item.Commodity_Code+"，商品名称："+item.Commodity_CName+"，数量超过库存量");
                        return result;
                    }

                    orderentity.AddOrChangeItem(dto.Code, orderLineItem_Commodity, item.Count);
                }
                await _checkoutorderLineItemRepository.InsertManyAsync(orderentity.CheckOutOrderLineItem);
                var post = await _checkoutorderRepository.InsertAsync(orderentity);
                await _unitOfWorkManager.Current.SaveChangesAsync();
                if (post == null)
                {
                    result.IsFailed(ResponseText.INSERT_FAILED);
                    return result;
                }

                result.IsSuccess(ResponseText.INSERT_SUCCESS);


            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                result.IsFailed(ResponseText.INSERT_FAILED);
            }

            return result;
        }

        /// <summary>
        /// 修改订单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<ServiceResult<string>> UpdateOrderAsync(UpdateCheckOutOrderDto dto)
        {
            var result = new ServiceResult<string>();
            try
            {
                //查询是否有该订单
                var entityExist = await _checkoutorderRepository.FindAsync(x => x.Code == dto.Code);
                if (entityExist == null)
                {
                    result.IsFailed(ResponseText.UPDATE_FAILED + ",没有该订单");
                    return result;
                }
                //状态校验
                if (entityExist.IsDraft != OrderStatusCode.Draft)
                {
                    result.IsFailed(ResponseText.UPDATE_FAILED + ",该订单已审核");
                    return result;
                }

                //订单修改时间
                entityExist.UpdateTime = DateTime.Now;
                entityExist.Description = dto.Description;
                //旧版订单明细   
                var orderLineItementity = _checkoutorderLineItemRepository.Where(x => x.CheckOutOrderCode == dto.Code).ToList();
                //订单明细调整
                foreach (var item in dto.CheckOutItem)
                {
                    //订单明细商品
                    var orderLineItem_Commodity = new OrderLineItem_Commodity(item.Commodity_Code, item.Commodity_CName, item.Commodity_CPrice);
                    //发布供应商校验事件
                    await PublishCommodityAsync(orderLineItem_Commodity);

                    entityExist.AddOrChangeItem(dto.Code, orderLineItem_Commodity, item.Count,true);
                }

                await _checkoutorderLineItemRepository.DeleteManyAsync(orderLineItementity);//删除旧版明细
                await _checkoutorderLineItemRepository.InsertManyAsync(entityExist.CheckOutOrderLineItem);//新增新版明细
                var post = await _checkoutorderRepository.UpdateAsync(entityExist);
                await _unitOfWorkManager.Current.SaveChangesAsync();
                if (post == null)
                {
                    result.IsFailed(ResponseText.UPDATE_FAILED);
                    return result;
                }

                result.IsSuccess(ResponseText.UPDATE_SUCCESS);
                return result;


            }
            catch (Exception ex)
            {
                _logger.LogCritical(ex.ToString());
                result.IsFailed(ResponseText.UPDATE_FAILED);
            }

            return result;
        }

        /// <summary>
        ///删除订单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>

        [HttpDelete]
        public async Task<ServiceResult<string>> DeleteOrderAsync(string code)
        {
            var result = new ServiceResult<string>();
            try
            {
                //查询是否有该订单
                var entityExist = await _checkoutorderRepository.FindAsync(x => x.Code == code);
                if (entityExist == null)
                {
                    result.IsFailed(ResponseText.DELETE_FAILED + ",没有该订单");
                    return result;
                }
                //状态校验
                if (entityExist.IsDraft != OrderStatusCode.Draft)
                {
                    result.IsFailed(ResponseText.DELETE_FAILED + ",该订单已审核");
                    return result;
                }

                //订单明细   
                var orderLineItementity = _checkoutorderLineItemRepository.Where(x => x.CheckOutOrderCode == code).ToList();

                await _checkoutorderLineItemRepository.DeleteManyAsync(orderLineItementity);
                await _checkoutorderRepository.DeleteAsync(entityExist);
                await _unitOfWorkManager.Current.SaveChangesAsync();

                result.IsSuccess(ResponseText.DELETE_SUCCESS);


            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                result.IsFailed(ResponseText.DELETE_FAILED);
            }

            return result;
        }

        /// <summary>
        /// 根据订单号查询订单
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ServiceResult<CheckOutOrderDto>> GetOrderAsync(string code)
        {
            ServiceResult<CheckOutOrderDto> result = new ServiceResult<CheckOutOrderDto>();
            try
            {
                var entity = await _checkoutorderRepository.FindAsync(x => x.Code == code);
                // var temp= await _checkoutorderRepository.WithDetailsAsync(x => x.Code == code);
                if (entity == null)
                {
                    result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("订单号", code));
                    return result;
                }
                result.IsSuccess("ok");
                //返回dto
                CheckOutOrderDto dto = new CheckOutOrderDto()
                {
                    Code = entity.Code,
                    Count = entity.Count,
                    CreationTime = entity.CreationTime,
                    ApplyUser=entity.ApplyUser,
                    Description=entity.Description,     
                    TotalPrice = entity.TotalPrice,
                    UpdateTime = entity.UpdateTime
                };
                //订单明细   
                List<CheckOutLineItemDto> list = new List<CheckOutLineItemDto>();
                var orderLineItementity = _checkoutorderLineItemRepository.Where(x => x.CheckOutOrderCode == code).ToList();
                foreach (var item in orderLineItementity)
                {
                    list.Add(new CheckOutLineItemDto
                    {
                        CheckOutOrderCode = item.CheckOutOrderCode,
                        LineNumber = item.LineNumber,
                        Commodity_Code = item.Commodity_Code,
                        Commodity_CName = item.Commodity_CName,
                        Commodity_CPrice = item.Commodity_CPrice,
                        Count = item.Count,
                        CreationTime = item.CreationTime,
                        Subtotal = item.Subtotal,
                        UpdateTime = item.UpdateTime
                    });
                }
                dto.CheckOutOrderLineItem = list;
                result.Result = dto;

            }
            catch (Exception ex)
            {
                result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("订单号", code));
                _logger.LogError(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 订单审核
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ServiceResult<string>> CheckOrderAsync(string code)
        {
            var result = new ServiceResult<string>();
            try
            {
                Dictionary<string, int> dic = new Dictionary<string, int>();
                //查询是否有该订单
                var entityExist = await _checkoutorderRepository.FindAsync(x => x.Code == code);
                if (entityExist == null)
                {
                    result.IsFailed("不存在该订单");
                    return result;
                }
                //状态校验
                if (entityExist.IsDraft != OrderStatusCode.Draft)
                {
                    result.IsFailed("该订单已审核");
                    return result;
                }
                entityExist.IsDraft = OrderStatusCode.NoDraft;
                entityExist.CheckTime = DateTime.Now;
                entityExist.CheckOutOrderLineItem = _checkoutorderLineItemRepository.Where(x => x.CheckOutOrderCode == code).OrderBy(x => x.Commodity_Code).ToList();
                foreach (var item in entityExist.CheckOutOrderLineItem)
                { 
                    #region 校验库存量 
                    var orderLineItem_Commodity = new OrderLineItem_Commodity(item.Commodity_Code, item.Commodity_CName, item.Commodity_CPrice);
                    //发布商品校验事件
                    var count = await PublishCommodityAsync(orderLineItem_Commodity);
                    if (count < item.Count)
                    {
                        result.IsFailed(ResponseText.INSERT_FAILED + ",商品编号：" + item.Commodity_Code + "，商品名称：" + item.Commodity_CName + "，库存量不够");
                        return result;
                    } 
                    #endregion

                    dic.Add(item.Commodity_Code, -(item.Count));
                }

                //发布商品出库事件
                await PublishCheckOrderAsync(dic);


                var post = await _checkoutorderRepository.UpdateAsync(entityExist);
                await _unitOfWorkManager.Current.SaveChangesAsync();
                if (post == null)
                {
                    result.IsFailed("审核失败");
                    return result;
                }
                result.IsSuccess("审核成功");


            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                result.IsFailed("审核失败");
            }
            return result;
        }


        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize"></param>
        /// <param name="orderNo"></param>
        /// <param name="isDraft"></param>
        /// <param name="beginTime"></param>
        /// <param name="endtime"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ServiceResult<PagedList<SelectCheckOutOrderDto>>> GetOrderListAsync(int pageIndex = 1, int pageSize = 10, string orderNo = "", OrderStatusCode isDraft = OrderStatusCode.All, string beginTime = "1990-10-15", string endtime = "")
        {
            var result = new ServiceResult<PagedList<SelectCheckOutOrderDto>>();
            try
            {
                //校验时间
                if ((!string.IsNullOrEmpty(beginTime) && !string.IsNullOrEmpty(endtime)) && (DateTime.Compare(Convert.ToDateTime(beginTime), Convert.ToDateTime(endtime)) > 0))
                {
                    result.IsFailed("查询失败,开始时间大于结束时间");
                    return result;
                }

                if (string.IsNullOrEmpty(endtime))
                    endtime = DateTime.Now.ToShortDateString();




                var entitylist = (from orders in await _checkoutorderRepository.GetListAsync()
                                  where (string.IsNullOrEmpty(orderNo) || orders.Code.Contains(orderNo))
                                         && ((isDraft == OrderStatusCode.All) || orders.IsDraft == isDraft)
                                         && ((string.IsNullOrEmpty(beginTime) && string.IsNullOrEmpty(endtime)) || (orders.CreationTime >= Convert.ToDateTime(beginTime) && orders.CreationTime <= Convert.ToDateTime(endtime).AddDays(1)))
                                  orderby orders.CreationTime descending
                                  select new SelectCheckOutOrderDto
                                  {
                                      Code = orders.Code,
                                      ApplyUser = orders.ApplyUser,
                                      Description=orders.Description,
                                      Count = orders.Count,
                                      TotalPrice = orders.TotalPrice,
                                      CreationTime = orders.CreationTime,
                                      IsDraft = orders.IsDraft
                                  }).OrderByDescending(m => m.CreationTime);

                if (pageIndex < 0 || pageSize < 0)
                {
                    var list = entitylist.ToList();
                    result.IsSuccess(new PagedList<SelectCheckOutOrderDto>(list.Count, list));
                }
                else
                {
                    var list = entitylist.Skip(pageSize * (pageIndex - 1)).Take(pageSize).ToList();
                    result.IsSuccess(new PagedList<SelectCheckOutOrderDto>(list.Count, list.ToList()));
                }

            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                result.IsFailed("查询失败");
            }

            return result;
        }


        #endregion


        #region 明细操作
        /// <summary>
        /// 追加明细
        /// </summary>
        /// <param name="code">订单号</param>
        /// <param name="dto">明细</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ServiceResult<string>> AddOrderLineItemAsync(string code, CheckOutItemDto dto)
        {
            var result = new ServiceResult<string>();
            try
            {
                //查询是否有该订单
                var entityExist = await _checkoutorderRepository.FindAsync(x => x.Code == code);
                if (entityExist == null)
                {
                    result.IsFailed(ResponseText.INSERT_FAILED + ",不存在该订单");
                    return result;
                }
                //状态校验
                if (entityExist.IsDraft != OrderStatusCode.Draft)
                {
                    result.IsFailed(ResponseText.INSERT_FAILED + ",该订单已审核");
                    return result;
                }

                //发布供应商校验事件
                var orderLineItem_Commodity = new OrderLineItem_Commodity(dto.Commodity_Code, dto.Commodity_CName, dto.Commodity_CPrice);
                await PublishCommodityAsync(orderLineItem_Commodity);

                //如果有该商品则修改商品数量，没有该商品则追加一条

                //查询原明细
                var orderLineItemList = _checkoutorderLineItemRepository.Where(x => x.CheckOutOrderCode == code).ToList();

                bool isInsert = entityExist.AddItem(code, orderLineItem_Commodity, dto.Count, orderLineItemList);
                if (isInsert)
                {
                    await _checkoutorderLineItemRepository.InsertAsync(entityExist.CheckOutOrderLineItem.Last<CheckOutOrderLineItem>());
                }
                else
                {
                    await _checkoutorderLineItemRepository.UpdateManyAsync(entityExist.CheckOutOrderLineItem);
                }

                var post = await _checkoutorderRepository.UpdateAsync(entityExist);
                await _unitOfWorkManager.Current.SaveChangesAsync();
                if (post == null)
                {
                    result.IsFailed(ResponseText.INSERT_FAILED);
                    return result;
                }

                result.IsSuccess(ResponseText.INSERT_SUCCESS);

            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                result.IsFailed(ResponseText.INSERT_FAILED);
            }
            return result;
        }

        /// <summary>
        /// 修改明细
        /// </summary>
        /// <param name="code">订单号</param>
        /// <param name="dto">明细</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ServiceResult<string>> UpdateOrderLineItemAsync(string code, CheckOutItemDto dto)
        {
            var result = new ServiceResult<string>();
            try
            {
                //查询是否有该订单
                var entityExist = await _checkoutorderRepository.FindAsync(x => x.Code == code);
                if (entityExist == null)
                {
                    result.IsFailed(ResponseText.UPDATE_FAILED + ",不存在该订单");
                    return result;
                }
                //状态校验
                if (entityExist.IsDraft != OrderStatusCode.Draft)
                {
                    result.IsFailed(ResponseText.UPDATE_FAILED + ",该订单已审核");
                    return result;
                }
                //发布供应商校验事件
                var orderLineItem_Commodity = new OrderLineItem_Commodity(dto.Commodity_Code, dto.Commodity_CName, dto.Commodity_CPrice);
                await PublishCommodityAsync(orderLineItem_Commodity);

                //查询原明细
                var orderLineItemList = _checkoutorderLineItemRepository.Where(x => x.CheckOutOrderCode == code).ToList();

                entityExist.ChangeItem(code, orderLineItem_Commodity, dto.Count, orderLineItemList);
                await _checkoutorderLineItemRepository.UpdateManyAsync(entityExist.CheckOutOrderLineItem);
                var post = await _checkoutorderRepository.UpdateAsync(entityExist);
                await _unitOfWorkManager.Current.SaveChangesAsync();
                if (post == null)
                {
                    result.IsFailed(ResponseText.UPDATE_FAILED);
                    return result;
                }

                result.IsSuccess(ResponseText.UPDATE_SUCCESS);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                result.IsFailed(ResponseText.UPDATE_FAILED);
            }
            return result;
        }

        /// <summary>
        /// 删除明细
        /// </summary>
        /// <param name="code">订单号</param>
        /// <param name="lineNumber">行号</param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<ServiceResult<string>> DeleteOrderLineItemAsync(string code, int lineNumber)
        {
            var result = new ServiceResult<string>();
            try
            {
                //查询是否有该订单
                var entityExist = await _checkoutorderRepository.FindAsync(x => x.Code == code);
                if (entityExist == null)
                {
                    result.IsFailed(ResponseText.DELETE_FAILED + ",不存在该订单");
                    return result;
                }
                //状态校验
                if (entityExist.IsDraft != OrderStatusCode.Draft)
                {
                    result.IsFailed(ResponseText.DELETE_FAILED + ",该订单已审核");
                    return result;
                }

                //查询原明细
                var orderLineItemList = _checkoutorderLineItemRepository.Where(x => x.CheckOutOrderCode == code).ToList();
                var orderLineItem = orderLineItemList.FirstOrDefault(x => x.LineNumber == lineNumber);
                if (orderLineItem == null)
                {
                    result.IsFailed(ResponseText.DELETE_FAILED + ",不存在该行号订单明细");
                }
                else
                {
                    orderLineItemList.Remove(orderLineItem);
                    entityExist.DeleteItem(code, orderLineItemList);
                    await _checkoutorderLineItemRepository.DeleteAsync(orderLineItem);
                    await _checkoutorderRepository.UpdateAsync(entityExist);
                    await _unitOfWorkManager.Current.SaveChangesAsync();
                    result.IsSuccess(ResponseText.DELETE_SUCCESS);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                result.IsFailed(ResponseText.DELETE_FAILED);
            }
            return result;
        }


        #endregion


        #region 发布事件
        /// <summary>
        /// 发布校验商品事件
        /// </summary>
        private async Task<int> PublishCommodityAsync(OrderLineItem_Commodity commodity)
        {
            OrderCommodityEto eto = new OrderCommodityEto(commodity);
            await _localEventBus.PublishAsync(eto);
            return eto.Count;
        }

        /// <summary>
        /// 发布订单审核后商数量变化
        /// </summary>
        /// <param name="dic"></param>
        /// <returns></returns>
        private async Task PublishCheckOrderAsync(Dictionary<string, int> dic)
        {
            CheckedCommodityCountEto eto = new CheckedCommodityCountEto(dic);
            await _localEventBus.PublishAsync(eto);
        }
        #endregion

        #region 订阅事件

        #endregion



    }
}
